package org.epidroid.epidroid.androsoul.ui.utils;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.epidroid.epidroid.R;
import org.epidroid.epidroid.androsoul.engine.service.IAndroSoulService;
import org.epidroid.epidroid.androsoul.ui.conversation.LoginAlertDialog;

import android.app.Activity;
import android.content.Context;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ClickableSpan;
import android.text.style.ImageSpan;
import android.util.Log;
import android.view.View;

public class TextFormater {

	private static final HashMap<String, Integer> emoticons = new HashMap<String, Integer>();
	static {
		emoticons.put(":)", R.drawable.happy);
		emoticons.put(":D", R.drawable.bighappy);
		emoticons.put("=D", R.drawable.bighappy);
		emoticons.put(":p", R.drawable.tongue);
		emoticons.put("=p", R.drawable.tongue);
		emoticons.put(":(", R.drawable.sad);
		emoticons.put("=(", R.drawable.sad);
		emoticons.put(";)", R.drawable.blink);
	}

	private static ArrayList<String> mLogins = new ArrayList<String>();
	
	/**
	 * Pattern of a login.
	 */
	private static final Pattern _login = Pattern
			.compile("([a-zA-Z-]{2,6}_\\S)(\\s*)");
	
	/**
	 * Return the <code>Spannable</code> build from the <parameter>text</parameter>
	 * Smileys and logins's link are Spannable.
	 * @param context
	 * @param text
	 * @return
	 */
	public static Spannable getSpannable(IAndroSoulService service, Activity activity, String text) {
		SpannableStringBuilder builder = new SpannableStringBuilder(text);
		buildLoginsList(text);
		for (int index = 0; index < builder.length(); index++) {
			insertSmiley(activity, index, builder);
			if (service != null)
				insertLoginLink(service, activity, index, builder);
		}
		return builder;
	}
	
	private static void insertLoginLink(final IAndroSoulService service,
			final Activity activity, int index, SpannableStringBuilder builder) {
		for (final String entry : mLogins) {
			int length = entry.length();
			if (index + length > builder.length())
				continue;
			if (builder.subSequence(index, index + length).toString().equals(entry)) {
				ClickableSpan is = new ClickableSpan() {
					
					@Override
					public void onClick(View widget) {
						Log.d("TAG", "Item clicked " + entry);
						
						LoginAlertDialog addContact = new LoginAlertDialog(service, activity);
						addContact.showContact(entry);
					}
				};

				builder.setSpan(is, index, index + length,
						Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
				index += length - 1;
				break;
			}
		}
	}
	
	/**
	 * 
	 * @param context
	 * @param index
	 * @param builder
	 */
	private static void insertSmiley (Context context, int index, SpannableStringBuilder builder) {
		for (Entry<String, Integer> entry : emoticons.entrySet()) {
			int length = entry.getKey().length();
			if (index + length > builder.length())
				continue;
			if (builder.subSequence(index, index + length).toString()
					.equals(entry.getKey())) {
				ImageSpan is = new ImageSpan(context, entry.getValue(),
						ImageSpan.ALIGN_BASELINE);

				builder.setSpan(is, index, index + length,
						Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
				index += length - 1;
				break;
			}
		}
	}

	/**
	 * Build the logins list from the text. All logins in <parameter>text></parameter>
	 * will be inserted in <code>mLogins</code>.
	 * @param text
	 */
	private static void buildLoginsList (String text) {
		Matcher match = _login.matcher(text);
		mLogins.clear();
		while (match.find()) {
			String login = match.group(1);
			Log.d("TAG", "AndroLinkify " + login);
			mLogins.add(login);
		}
	}
	
	public static String reduceString(String str, int s) {
		if (str.length() <= s)
			return str;
		return str.substring(0, s) + "...";
	}

	public static String decodeUTF8(String data) {
		try {
			return new String(data.getBytes(), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			return data;
		}
	}
}
